package com.qf.config;

import com.qf.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.HashSet;
import java.util.Set;

/**
 *
 * UserDetailsService 这个是Security框架提供的接口
 * 我们需要实现这个接口，来自己查询数据库获得用户信息
 * 框架会调用这个方法，来获取用户信息
 *
 * UserDetailsService是两个接口之一，另一个是UserDetails
 * UserDetailsService是获取用户信息的主要就是登录时调用的
 * UserDetails是获取用户信息的主要就是登录成功后调用的
 *
 */
@Service
public class UserDetailServiceImpl implements UserDetailsService {

    @Autowired
    private UserMapper userMapper;

    /**
     * 这个方法是框架调用的
     * 我们需要在这个方法中查询数据库，根据用户名查询用户信息
     * 强调的是,是根据用户名查的,即不需要传递密码
     * 因为根据用户名查到用户后,框架会自动对密码进行匹配
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

        // 调用mapper查询用户信息
        com.qf.entity.User user = userMapper.selectByUsername(username);

        /**
         * 如果用户不存在,则抛出异常
         */
        if (user == null) {
            throw new UsernameNotFoundException("用户名不存在");
        }

        /**
         * 如果用户存在,则查询该用户的所有权限,转换为 GrantedAuthority 类型,并添加到集合中
         */
        Set<String> authsSet = userMapper.selectAuthsById(user.getId());

        Set<GrantedAuthority> auths = new HashSet<>();
        /**
         * 遍历权限集合,将每个权限转换为 GrantedAuthority 类型,并添加到集合中
         */
        authsSet.forEach(auth->{
            auths.add(new SimpleGrantedAuthority(auth));
        });
        // 该方法返回的是 org.springframework.security.core.userdetails.User对象
        // 这个对象需要传入3个参数,用户名,密码,权限
        return new org.springframework.security.core.userdetails.User(user.getUsername(),user.getPassword(),auths);
    }
}